﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SLNGP.Common.Extensions;
using SLNGP.Common.IoC;
using SLNGP.Core;
using SLNGP.Core.Fitness;
using SLNGP.Core.Genes;
using SLNGP.Core.GeneticPrograms;
using SLNGP.Core.Individuals;

namespace SLNGP.Test.Samples
{
    /// <summary>
    /// Sample files are code samples meant to target and document how to use SLNGP. 
    /// Samples are not meant to be unit tests.
    /// However, Samples can be run as unit tests, though results are random and irrelevant. 
    /// </summary>
    [Ignore]
    [TestClass]
    public class BasicSamples
    {
        [TestMethod]
        public void SettingUpAnXPlus1GeneticProgram()
        {
            Dictionary<int, int> testData = new Dictionary<int, int>();
            for (int i = 0; i <= 100; i++)
                testData[i] = i + 3;

            IGeneticProgram gp = new PreconfiguredGeneticProgram();
            gp.AddPossibleGenes(Genes.MathFunctions.Add, 
                                Genes.Variable<int>("X"),
                                Genes.Constant(1));
            
            gp.FitnessFunction = new SingleIndivdualFitnessFunction<int>(individual => 
            {
                int sumDistance = 0;
                foreach (var pair in testData)
                    sumDistance += Math.Abs(individual.ExecuteScalar<int>("X", pair.Key) - pair.Value);
                return sumDistance;
            });
            gp.FitnessFunction.FitnessFunctionOrder = FitnessFunctionOrder.LowerIsBetter;
            
            gp.StopRunConditions.IndividualStopCondition = ((IIndividual individual) => individual.Fitness.As<int>() == 0);
            gp.RunUntilStopCondition(); 

            Debug.WriteLine(gp.LastRunResults.Generations.Count - 1 + " Generations.");
            foreach(IIndividual lastGenerationIndividual in gp.LastRunResults.LastGeneration)
            {
                string formula = lastGenerationIndividual.Chromosome.GetStringDisplay();
                Debug.WriteLine(string.Format("{0} fitness: {1}", lastGenerationIndividual.Fitness.ToString(), formula));
            }
        }

        [TestInitialize]
        public void TestInitialize()
        {
            // pretend these are real samples
            Initializer.IsTesting = false;
            Initializer.InitializeIoC();
        }
    }
}


